-
Notifications
You must be signed in to change notification settings - Fork 1
[Feature/#199] 나의 푸드트럭 등록 / 수정 api / 리뷰 XXXX #214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Walkthroughroute param 기반 foodTruckId로 폼 초기화·검증 흐름 전환, 날짜 유틸 리네임 및 역변환 추가, 폼 리셋/포맷 유틸·업데이트 뮤테이션·토스트 알림 도입, region/upload/menu 흐름에서 formData 상태 기반 라우팅 전파가 추가됨. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant UI as FoodTruckForm UI
participant Hook as useFoodTruckForm
participant Query as API/Queries
participant Mut as useMutationFoodTruckForm
participant Router as Router/Toast
UI->>Hook: mount(foodTruckId)
Hook->>Query: fetch foodTruckDetail (enabled: !!foodTruckId)
Hook->>Query: fetch menus
Query-->>Hook: detail + menus
Hook->>Hook: resetFoodTruckFormValue(detail, menus)
UI->>Hook: submit(formData)
Hook->>Mut: updateFoodTruckInfo({ foodTruckId, data: formatFoodTruckForm(formData) })
Mut->>Query: PUT /food-trucks/{id}
Query-->>Mut: response
alt success
Mut->>Router: toast.success, invalidate cache, navigate(FOOD_TRUCK_MANAGEMENT)
else error
Mut->>Router: toast.error
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 4❌ Failed checks (3 warnings, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (2)
src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
13-13: ID 검증 로직을 더 명확하게 개선하세요.
enabled: !!foodTruckId는 0을 허용합니다. 푸드트럭 ID가 1부터 시작한다면enabled: foodTruckId > 0이 더 명확합니다.🔎 제안하는 수정
- enabled: !!foodTruckId, + enabled: foodTruckId > 0,src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
56-80: 여러 번의 리렌더링 가능성을 고려해주세요.
foodTruckDetailData와menuData가 서로 다른 시점에 로드되면 폼이 여러 번 리셋될 수 있습니다. 또한 API 호출 실패 시 에러 처리가 없습니다.💡 한 번만 리셋하도록 개선하는 제안
두 데이터가 모두 준비된 후 한 번만 리셋하도록 수정할 수 있습니다:
useEffect(() => { - if (foodTruckDetailData) { + if (foodTruckDetailData && menuData !== undefined) { setIsEdit(true); reset({ // ... 기존 코드 }); } }, [foodTruckDetailData, menuData, reset]);또는 두 API 호출이 모두 완료될 때까지 대기하는 로딩 상태를 추가할 수 있습니다.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/pages/@owner/estimate/hooks/use-estimate-form.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsxsrc/pages/@owner/food-truck-form/constants/food-truck.tssrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/food-truck-detail/hooks/use-food-truck-detail.tssrc/shared/constant/need-electricity.tssrc/shared/constant/payment-method.tssrc/shared/utils/date/date-formatter.ts
🧰 Additional context used
🧬 Code graph analysis (4)
src/pages/@owner/estimate/hooks/use-estimate-form.ts (1)
src/shared/utils/date/date-formatter.ts (1)
formatStringDatesToAvailableDates(73-102)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (4)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
foodTruckSchema(12-65)src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
useFoodTruckDetail(16-46)src/pages/@owner/menu/hooks/use-menus-query.ts (1)
useMenusQuery(6-25)src/shared/utils/date/date-formatter.ts (1)
formatStringDatesToAvailableDates(73-102)
src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
apis/data-contracts.ts (1)
FoodTruckDetailResponse(1427-1517)
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (3)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(33-103)src/router/constant/routes.ts (1)
ROUTES(1-33)src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx (1)
RegionSection(15-46)
🔇 Additional comments (10)
src/pages/@owner/estimate/hooks/use-estimate-form.ts (1)
9-9: LGTM!함수 이름 변경에 맞춰 import와 사용처가 올바르게 업데이트되었습니다.
Also applies to: 70-72
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (2)
82-82: LGTM!
isEdit플래그에 따라 제목을 동적으로 표시하는 로직이 적절합니다.
97-97: LGTM!
RegionSection에foodTruckId를 전달하여 지역 데이터를 로드할 수 있도록 개선되었습니다.src/pages/@owner/food-truck-form/constants/food-truck.ts (1)
26-26: 백엔드 API와의 호환성 확인됨 - 추가 검증 불필요변경사항이 다음 항목들과 호환되는 것으로 확인되었습니다:
- 백엔드 API:
apis/data-contracts.ts라인 269에서 이미@maxItems 4로 정의되어 있음- UI 처리:
ActiveDate.tsx,ScheduleCalendar.tsx등의 컴포넌트가 날짜 범위를 동적으로 처리하므로 4개 제한 수용 가능- 폼 검증:
food-truck-form.schema.ts에서FOOD_TRUCK_MAX_LENGTH.availableDates.max를 참조하므로 자동으로 새로운 값 적용됨- 에러 메시지: 템플릿 기반이므로 상수값 변경 시 자동 반영됨
src/shared/utils/date/date-formatter.ts (1)
68-75: 함수 이름 변경이 적절하게 완료되었습니다.
formatEstimateDatesToAvailableDates를formatStringDatesToAvailableDates로 변경하여 함수의 범용성을 더 잘 표현하고 있으며, JSDoc도 적절히 업데이트되었습니다. 모든 호출처(use-food-truck-form.ts,use-estimate-form.ts)가 정상적으로 업데이트되었고, 이전 함수명의 남은 참조는 없습니다.src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (5)
1-12: LGTM!새로운 기능에 필요한 import들이 올바르게 추가되었습니다.
95-103: LGTM!
isEdit상태를 반환값에 추가하여 컴포넌트에서 편집 모드를 판단할 수 있도록 한 것이 적절합니다.
50-54: 두 훅 모두 이미 유효하지 않은 ID로부터 보호되어 있습니다.
useFoodTruckDetail과useMenusQuery모두enabled: !!foodTruckId조건부 실행 로직을 포함하고 있으므로, 무효한 ID가 전달될 경우 API 호출이 실행되지 않습니다. 현재 구현이 이미 적절한 보호를 제공하고 있어 추가 수정이 필요하지 않습니다.Likely an incorrect or invalid review comment.
33-48: 문제 없습니다.useFoodTruckDetail과useMenusQuery훅 모두enabled: !!foodTruckId조건을 통해 유효하지 않은 ID로 인한 불필요한 API 호출을 이미 방지하고 있습니다. 새로운 푸드트럭 등록 시foodTruckIdNumber가 NaN이 되면 쿼리가 실행되지 않으므로 추가 검증이 필요하지 않습니다.
69-69: 이 코드는 타입 오류가 없습니다.FoodTruckDetailResponse.photoUrl은 이미string[]배열로 정의되어 있으며, 폼 필드photoUrls도string[]을 기대합니다.
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts
Outdated
Show resolved
Hide resolved
빌드 및 린트 결과모든 검사 통과 🎉
|
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (1)
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (1)
69-72: return 문이 누락되어 잘못된 렌더링이 발생합니다.유효성 검증 후
return null이 없어서 토스트와 navigate 호출 후에도 컴포넌트가 계속 렌더링됩니다. 이는 예상치 못한 동작과 에러를 발생시킬 수 있습니다.🔎 제안하는 수정
if (!foodTruckId || isNaN(foodTruckIdNumber)) { toast.error('잘못된 접근입니다.'); navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return null; }더 나은 사용자 경험을 위해 useEffect로 처리하는 방법도 고려하세요:
+ useEffect(() => { + if (!foodTruckId || isNaN(foodTruckIdNumber)) { + toast.error('잘못된 접근입니다.'); + navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + } + }, [foodTruckId, foodTruckIdNumber, toast, navigate]); + if (!foodTruckId || isNaN(foodTruckIdNumber)) { - toast.error('잘못된 접근입니다.'); - navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return null; }
🧹 Nitpick comments (2)
src/shared/utils/normalize-enum-value.ts (1)
1-11: LGTM!유틸리티 함수의 로직이 올바르며 enum 값 정규화를 안전하게 처리합니다.
💡 더 간결한 구현 제안 (선택사항)
타입 캐스팅을 줄이고 가독성을 개선할 수 있습니다:
export const normalizeEnumValue = <T extends Record<string, string>>( enumObj: T, value?: string ): T[keyof T] | undefined => { if (!value) return undefined; const values = Object.values(enumObj) as Array<T[keyof T]>; - return values.includes(value as T[keyof T]) - ? (value as T[keyof T]) - : undefined; + return values.includes(value as T[keyof T]) ? value as T[keyof T] : undefined; };src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
61-95: useEffect 의존성 배열을 최적화하세요.
menuData가 의존성에 포함되어 메뉴 페이지가 로드될 때마다 useEffect가 재실행됩니다. infinite query의 특성상 스크롤 시에도 트리거될 수 있습니다.🔎 제안하는 최적화
데이터 로딩 완료 시점만 감지하도록 변경:
+ const isDataLoaded = !!foodTruckDetailData && menuData !== undefined; + useEffect(() => { if (foodTruckDetailData) { const menus = menuData?.pages.flatMap(page => page?.content || []); setIsEdit(true); reset({ // ... form data }); } - }, [foodTruckDetailData, menuData, reset]); + }, [isDataLoaded, reset]);또는 초기 로드만 처리:
+ const [isInitialized, setIsInitialized] = useState(false); + useEffect(() => { - if (foodTruckDetailData) { + if (foodTruckDetailData && !isInitialized) { const menus = menuData?.pages.flatMap(page => page?.content || []); setIsEdit(true); reset({ // ... form data }); + setIsInitialized(true); } - }, [foodTruckDetailData, menuData, reset]); + }, [foodTruckDetailData, menuData, isInitialized, reset]);
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/pages/@owner/food-truck-form/FoodTruckForm.tsxsrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/shared/utils/normalize-enum-value.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (7)
src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
useFoodTruckDetail(16-46)src/pages/@owner/menu/hooks/use-menus-query.ts (1)
useMenusQuery(6-25)src/shared/utils/normalize-enum-value.ts (1)
normalizeEnumValue(1-11)src/shared/constant/available-quantity.ts (1)
AVAILABLE_QUANTITY(1-7)src/shared/constant/need-electricity.ts (1)
NEED_ELECTRICITY(1-5)src/shared/constant/payment-method.ts (1)
PAYMENT_METHOD(1-5)src/shared/utils/date/date-formatter.ts (1)
formatStringDatesToAvailableDates(73-102)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (3)
src/shared/constant/available-quantity.ts (1)
AVAILABLE_QUANTITY(1-7)src/shared/constant/need-electricity.ts (1)
NEED_ELECTRICITY(1-5)src/shared/constant/payment-method.ts (1)
PAYMENT_METHOD(1-5)
🔇 Additional comments (4)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (2)
92-92: LGTM!메뉴 존재 여부 체크 로직이 올바르게 개선되었습니다.
menus.length !== 0확인으로 실제 메뉴 항목이 있는지 정확히 검증합니다.
84-84: 백엔드 API 필드명 수정이 필요합니다.
FoodTruckDetailResponse의photoUrl필드는 실제로string[]타입(배열)이지만, 필드명이 단수형입니다. 현재 코드에서 폼의photoUrls에 할당할 때 타입은 일치하지만, 네이밍 컨벤션이 불일치합니다.백엔드 API 응답 타입에서
photoUrl필드를 복수형photoUrls로 수정하거나, 명시적인 타입 변환을 추가하세요.src/pages/@owner/food-truck-form/FoodTruckForm.tsx (2)
45-46: LGTM!
useFoodTruckForm훅의 시그니처가 개선되어 ID 기반 데이터 로딩으로 리팩토링되었습니다.isEdit플래그 반환도 적절합니다.
81-81: LGTM!
isEdit플래그를 사용한 조건부 타이틀 렌더링이 깔끔하고 명확합니다.
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts
Outdated
Show resolved
Hide resolved
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (2)
78-81: enum 정규화 실패 시 UX를 개선하는 것을 고려하세요.
normalizeEnumValue가undefined를 반환할 때 에러 토스트를 표시하고 early return하는 것은 좋은 방어 로직입니다. 다만 사용자는 빈 폼만 보게 되므로, 필요시 기본값으로 폼을 채우거나 재시도 옵션을 제공하는 것을 고려해보세요.Based on past review comments, 이 로직은 이전 리뷰 피드백을 반영하여
normalizeEnumValue의undefined반환을 적절히 처리하고 있습니다.
101-101: 메뉴 체크 로직을 단순화할 수 있습니다.
flatMap은 항상 배열을 반환하므로menus !== undefined체크는 불필요합니다.menus.length > 0만으로 충분합니다.🔎 단순화 제안
- menus: menus !== undefined && menus.length !== 0, + menus: menus.length > 0,Based on past review comments, 이 로직은 이전 리뷰 피드백을 반영하여
menuData.pages를 올바르게 검사하고 실제 메뉴 컨텐츠가 있는지 확인합니다.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts
🧰 Additional context used
🪛 GitHub Check: build
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts
[warning] 104-104:
React Hook useEffect has a missing dependency: 'toast'. Either include it or remove the dependency array
🔇 Additional comments (4)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (4)
1-11: 새로운 의존성 추가를 확인했습니다.데이터 로딩, enum 정규화, 날짜 포맷팅, 토스트 기능을 위한 새로운 import가 적절하게 추가되었습니다.
57-61: 데이터 페칭 로직이 적절합니다.푸드트럭 상세 정보와 메뉴 데이터를 조회하는 훅 사용이 올바르게 구현되었습니다.
106-117: 제출 로직이 적절하게 구조화되어 있습니다.이름 중복 확인 검증과 TODO 주석이 명확합니다. 실제 API 호출 구현 시 에러 처리와 로딩 상태 관리를 추가하세요.
119-127: isEdit 상태가 반환 객체에 적절히 추가되었습니다.수정 모드 여부를 외부에 노출하여 UI가 적절히 대응할 수 있도록 합니다.
…Value 분리 / 최적화를 위해 useToast 리팩토링 TODO: 푸드트럭 사진 관련해서도 지역처럼 리팩토링 필요
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsx (1)
7-7: Import 경로에 오타가 있습니다.
@pages/@owner//food-truck-form에 슬래시가 중복되어 있습니다.🔎 수정 제안
-import { useFoodTruckForm } from '@pages/@owner//food-truck-form/hooks/use-food-truck-form'; +import { useFoodTruckForm } from '@pages/@owner/food-truck-form/hooks/use-food-truck-form';
🧹 Nitpick comments (4)
src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx (1)
35-44: 불필요한 null 체크를 간소화할 수 있습니다.Line 35에서
formData.regionCodes ?? []로 이미 빈 배열을 기본값으로 설정했으므로, Line 41의regionCodes &&체크는 불필요합니다.🔎 수정 제안
<RegionButton text={ - regionCodes && regionCodes.length > 0 + regionCodes.length > 0 ? regionCodes.map(region => region.name).join(', ') : '' }src/pages/@owner/set-region/hooks/use-region.ts (1)
15-47: 중복된 가드 로직을 추출하여 DRY 원칙을 적용할 수 있습니다.
handleSubmitRegion과handleResetRegionFoodTruck모두 동일한foodTruckId검증 로직을 포함하고 있습니다. 헬퍼 함수로 추출하면 유지보수성이 향상됩니다.🔎 수정 제안
+ const navigateToForm = (regionCodes: RegionResponse[]) => { + if (!foodTruckId) { + toast.error('잘못된 접근입니다.'); + navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return; + } + navigate(ROUTES.FOOD_TRUCK_FORM(foodTruckId), { + state: { + from: 'set-region', + formData: { + ...formData, + regionCodes, + }, + }, + }); + }; + const handleSubmitRegion = (regions: RegionResponse[]) => { - if (!foodTruckId) { - toast.error('잘못된 접근입니다.'); - navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); - return; - } - navigate(ROUTES.FOOD_TRUCK_FORM(foodTruckId), { - state: { - from: 'set-region', - formData: { - ...formData, - regionCodes: regions, - }, - }, - }); + navigateToForm(regions); }; const handleResetRegionFoodTruck = () => { - if (!foodTruckId) { - toast.error('잘못된 접근입니다.'); - navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); - return; - } - navigate(ROUTES.FOOD_TRUCK_FORM(foodTruckId), { - state: { - from: 'set-region', - formData: { - ...formData, - regionCodes: [], - }, - }, - }); + navigateToForm([]); };src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts (1)
12-56: 반환 타입을 명시적으로 정의하면 타입 안전성이 향상됩니다.현재 암시적 반환 타입 대신 discriminated union을 사용하면 호출 측에서 타입 가드를 더 명확하게 사용할 수 있습니다.
🔎 수정 제안
type ResetFormResult = | { isError: true; values?: never } | { isError: false; values: FoodTruckFormData }; export const resetFoodTruckFormValue = ( foodTruckDetailData: FoodTruckDetailResponse, menus?: MyFoodTruckMenuResponse[] ): ResetFormResult => { // ... existing implementation };src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
71-82: TODO 코멘트를 이슈로 관리하시겠습니까?Line 79에 푸드트럭 등록 API 호출이 TODO로 남아있습니다. PR 설명에서 언급하신 것처럼 아직 API 연동 전이라는 점을 이해합니다.
이 TODO를 별도 이슈로 생성하여 추적하시겠습니까? 생성을 원하시면 알려주세요.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsxsrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.tssrc/pages/@owner/set-region/SetRegion.tsxsrc/pages/@owner/set-region/hooks/use-region.tssrc/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsxsrc/shared/components/region/hooks/use-region.tssrc/shared/hooks/use-toast.ts
🧰 Additional context used
🧬 Code graph analysis (7)
src/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsx (1)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(35-92)
src/pages/@owner/set-region/hooks/use-region.ts (3)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
FoodTruckFormData(72-72)apis/data-contracts.ts (1)
RegionResponse(826-844)src/router/constant/routes.ts (1)
ROUTES(1-33)
src/shared/hooks/use-toast.ts (2)
src/shared/utils/toast.ts (1)
ToastAtom(11-17)src/shared/constant/toast.ts (1)
TOAST_TYPE(3-8)
src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx (2)
src/router/constant/routes.ts (1)
ROUTES(1-33)src/pages/@owner/food-truck-form/utils/navigate-state.tsx (1)
getNavigateState(3-8)
src/shared/components/region/hooks/use-region.ts (1)
src/shared/components/region/constant/region.ts (1)
MAX_SELECTED(1-1)
src/pages/@owner/set-region/SetRegion.tsx (2)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(35-92)src/pages/@owner/set-region/hooks/use-region.ts (1)
useRegion(8-55)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (3)
src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
useFoodTruckDetail(16-46)src/pages/@owner/menu/hooks/use-menus-query.ts (1)
useMenusQuery(6-25)src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts (1)
resetFoodTruckFormValue(12-57)
🔇 Additional comments (10)
src/shared/hooks/use-toast.ts (1)
9-32: LGTM! 참조 안정성을 위한 메모이제이션 적용이 적절합니다.
useCallback과useMemo를 사용하여 토스트 핸들러의 참조 안정성을 확보했습니다.addToast는 jotai의useSetAtom에서 반환되어 안정적인 참조를 가지므로 의존성 배열 구성도 올바릅니다.src/pages/@owner/set-region/hooks/use-region.ts (1)
50-50: 필수 파라미터에 대한 옵셔널 체이닝 사용을 확인해주세요.
formData는 필수 파라미터로 선언되어 있지만formData?.regionCodes에서 옵셔널 체이닝을 사용하고 있습니다. 타입 정의와 일치하도록 수정하거나, 실제로undefined가 전달될 수 있다면 파라미터 타입을formData?: FoodTruckFormData로 변경해주세요.src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts (1)
38-38:nameDuplicate: true하드코딩 의도를 확인해주세요.기존 푸드트럭 데이터 로드 시
nameDuplicate를 항상true로 설정하는 것이 의도된 동작인지 확인이 필요합니다. 수정 모드에서 이름 중복 체크를 건너뛰는 것이 맞다면, 해당 의도를 주석으로 명시하면 좋겠습니다.src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (7)
1-14: LGTM - 임포트 구성이 적절합니다.새로운 데이터 로딩 로직과 에러 처리를 위해 필요한 훅과 유틸리티들이 적절하게 추가되었습니다.
16-33: LGTM - 초기 데이터 구조가 완전합니다.폼의 모든 필수 필드가 적절한 초기값으로 정의되어 있습니다.
37-48: LGTM - React Hook Form 설정이 올바릅니다.폼 설정과 메서드 추출이 적절하게 구성되어 있습니다.
50-56: LGTM - 데이터 로딩 로직이 명확합니다.기존 푸드트럭 데이터와 메뉴 조회를 통해 수정 모드 여부를 판단하는 로직이 명확하게 구현되어 있습니다.
isEdit플래그가 데이터 존재 여부를 기반으로 적절하게 설정됩니다.
58-69: LGTM - useEffect 로직과 의존성 배열이 올바릅니다.기존 이슈였던
toast의존성이 배열에 포함되어 있고, 데이터 로딩 및 폼 리셋 로직이 적절하게 구현되어 있습니다. 에러 처리도 사용자에게 명확한 메시지를 제공합니다.
84-92: LGTM - 반환 값이 명확하고 완전합니다.
isEdit플래그와isFormValid(기존isValid에서 이름 개선)를 포함하여 필요한 모든 메서드와 상태를 적절하게 노출하고 있습니다.
35-36: 신규 푸드트럭 등록은 이 훅을 사용하지 않습니다. 새로운 푸드트럭은FoodTruckOnboarding페이지에서 별도의 흐름으로 등록되며, 등록 완료 후 ID가 생성되면FoodTruckForm페이지에서useFoodTruckForm훅을 사용하여 편집합니다. 따라서 현재 함수 시그니처(foodTruckIdNumber: number)는 정상 설계입니다.Likely an incorrect or invalid review comment.
src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx
Outdated
Show resolved
Hide resolved
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/pages/@owner/set-region/SetRegion.tsx (2)
36-36:location.statenull 안전성이 제거되어 런타임 에러가 발생할 수 있습니다.이전 리뷰에서 지적되었던 것처럼, 사용자가 URL로 직접 접근하거나 브라우저 히스토리를 통해 접근할 경우
location.state가null일 수 있습니다.현재 코드는 옵셔널 체이닝 없이
location.state.formData에 접근하므로,state가null일 때 런타임 에러가 발생합니다. 57-60번 줄의formData체크는 이 접근 이후에 실행되므로 에러를 방지할 수 없습니다.🔎 수정 제안
function SetRegionContent() { const { foodTruckId } = useParams(); const navigate = useNavigate(); const location = useLocation(); - const formData = location.state.formData; + const formData = location.state?.formData; + + if (!formData) { + navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return null; + } const handleLeftClick = () => { if (!foodTruckId) { navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); return; } const fromPage = location.state?.from; navigate(ROUTES.FOOD_TRUCK_FORM(foodTruckId), { state: { from: fromPage || 'food-truck-form', formData: formData, }, }); }; const { handleSubmitRegion, handleResetRegionFoodTruck } = useRegion( formData, foodTruckId ); - if (!formData) { - navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); - return null; - } return (
16-23: 유효성 검사가 훅 호출 이후에 실행되는 치명적인 순서 문제가 있습니다.18번 줄에서
useFoodTruckForm이 호출된 이후에 20-23번 줄에서 유효성 검사가 수행됩니다. 이로 인해:
- 유효하지 않은
foodTruckId(NaN)가 이미 훅에 전달됨navigate()호출 후에도 컴포넌트가 계속 렌더링되어 예상치 못한 동작 발생- 유효성 검사가 실질적으로 아무것도 방지하지 못함
React의 훅 규칙상 조건부 렌더링이 필요한 경우 유효성 검사를 훅 호출 이전에 수행하고 early return 해야 합니다.
🔎 수정 제안
export default function SetRegion() { const navigate = useNavigate(); const toast = useToast(); const { foodTruckId } = useParams(); const foodTruckIdNumber = Number(foodTruckId); - const methods = useFoodTruckForm(foodTruckIdNumber); if (!foodTruckId || isNaN(foodTruckIdNumber)) { toast.error('잘못된 접근입니다.'); navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return null; } + + const methods = useFoodTruckForm(foodTruckIdNumber); return ( <FormProvider {...methods.methods}> <SetRegionContent /> </FormProvider> ); }
🧹 Nitpick comments (1)
src/shared/components/region/hooks/use-region.ts (1)
21-32: 이전 리뷰 피드백이 반영되어 개선되었습니다.토글 로직이 명확하게 구현되었고,
toast.error()호출이setState업데이터 외부로 이동되어 이전 리뷰에서 지적된 사이드 이펙트 문제가 해결되었습니다.다만, 빠른 연속 클릭 시
selectedRegions.length체크(27번 줄)가 stale closure 값을 읽을 가능성이 있습니다. 더 엄격한 동시성 보장이 필요하다면 모든 상태 체크를 단일 함수형setState내부로 이동하는 것을 고려할 수 있습니다.🔎 선택적 개선 사항
const handleSelectRegion = (region: RegionResponse) => { - const alreadySelected = selectedRegions.some(r => r.code === region.code); - if (alreadySelected) { - setSelectedRegions(prev => prev.filter(r => r.code !== region.code)); - return; - } - if (selectedRegions.length >= MAX_SELECTED) { - toast.error('최대 선택 개수를 초과했습니다.'); - return; - } - setSelectedRegions(prev => [...prev, region]); + setSelectedRegions(prev => { + const alreadySelected = prev.some(r => r.code === region.code); + + if (alreadySelected) { + return prev.filter(r => r.code !== region.code); + } + + if (prev.length >= MAX_SELECTED) { + return prev; + } + + return [...prev, region]; + }); + + // 토스트는 상태 업데이트 후 useEffect나 별도 체크로 처리 + if (!selectedRegions.some(r => r.code === region.code) && + selectedRegions.length >= MAX_SELECTED) { + toast.error('최대 선택 개수를 초과했습니다.'); + } };
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsxsrc/pages/@owner/set-region/SetRegion.tsxsrc/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsxsrc/shared/components/region/hooks/use-region.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
src/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsx (2)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(35-92)src/router/constant/routes.ts (1)
ROUTES(1-33)
src/shared/components/region/hooks/use-region.ts (1)
src/shared/components/region/constant/region.ts (1)
MAX_SELECTED(1-1)
🔇 Additional comments (2)
src/pages/@owner/upload-food-truck-images/UploadFoodTruckImages.tsx (1)
1-5: LGTM!새로운 검증 로직에 필요한 import가 적절하게 추가되었습니다.
src/pages/@owner/set-region/SetRegion.tsx (1)
52-55:useRegion훅의 시그니처가 올바르게 적용되어 있습니다.코드베이스를 검증한 결과,
src/pages/@owner/set-region/SetRegion.tsx파일의useRegion(formData, foodTruckId)호출은 동일 디렉토리의 훅 정의(src/pages/@owner/set-region/hooks/use-region.ts)와 정확하게 일치합니다. 모든 호출 지점이 각각의 훅 정의에 맞게 올바르게 업데이트되어 있습니다.
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/upload-food-truck-images/hooks/use-upload-images.ts (1)
143-163: line 19에서 옵셔널 체이닝이 필요합니다. 현재 코드는 직접 네비게이션 시 런타임 오류를 발생시킵니다.
const formData = location.state.formData;는 사용자가 직접 이 페이지로 네비게이션할 경우location.state가null이 되어 크래시를 유발합니다. 코드베이스의 다른 파일들(MenuEdit.tsx,use-menu-list.ts,FoodTruckForm.tsx)은 모두 옵셔널 체이닝을 사용하고 있습니다.lines 143-163의 네비게이션 state 구조는 올바르지만, line 19가 수정되어야 이 부분이 정상 작동합니다.
다음과 같이 수정하세요:
- Line 19:
const formData = location.state?.formData;로 변경- Line 31:
formData?.photoUrls || []로 수정 (undefined 체크)- Line 147: spread 전에 formData 체크 추가
🧹 Nitpick comments (2)
src/pages/@owner/upload-food-truck-images/hooks/use-food-truck-image.ts (1)
42-55: 사용자 피드백 개선 및 일관성 검토 권장토스트 알림 추가로 사용자 피드백이 개선되었습니다. 다만 다음 사항들을 고려해보시기 바랍니다:
에러 메시지 구체성: 현재
onError는 범용 메시지('이미지 업로드 오류')를 표시하지만, API에서 던지는 구체적인 에러 정보를 활용하면 사용자가 문제를 더 쉽게 파악할 수 있습니다.일관성: 같은 파일의
useDeleteImage훅도 사용자 작업이지만 토스트 피드백이 없어 UX 일관성이 떨어집니다. 이미지 삭제 작업에도 성공/실패 알림 추가를 검토해보세요.🔎 에러 메시지 구체화 예시
onError: () => { - toast.error('이미지 업로드 오류'); + toast.error(error.message || '이미지 업로드 오류'); },또는 에러 파라미터를 활용:
- onError: () => { + onError: (error) => { toast.error('이미지 업로드 오류'); },src/pages/@owner/upload-food-truck-images/hooks/use-upload-images.ts (1)
19-40:formData에 타입 정의를 추가하는 것을 고려하세요.
formData가 타입 어노테이션 없이 사용되고 있어photoUrls같은 속성의 존재가 컴파일 타임에 보장되지 않습니다. 명시적인 타입을 정의하면 타입 안전성과 IDE 자동완성이 개선됩니다.🔎 타입 정의 예시
별도의 타입 파일에 인터페이스를 정의:
// types/food-truck-form.ts export interface FoodTruckFormData { photoUrls?: string[]; // 다른 폼 필드들... }그리고 훅에서 사용:
+import type { FoodTruckFormData } from '@/types/food-truck-form'; + export const useUploadImages = () => { const navigate = useNavigate(); const location = useLocation(); const { foodTruckId } = useParams<{ foodTruckId: string }>(); - const formData = location.state?.formData; + const formData = location.state?.formData as FoodTruckFormData | undefined;
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/pages/@owner/upload-food-truck-images/hooks/use-food-truck-image.tssrc/pages/@owner/upload-food-truck-images/hooks/use-upload-images.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/@owner/upload-food-truck-images/hooks/use-food-truck-image.ts (1)
src/pages/@owner/upload-food-truck-images/api/index.ts (1)
uploadImage(26-44)
🔇 Additional comments (1)
src/pages/@owner/upload-food-truck-images/hooks/use-food-truck-image.ts (1)
9-9: LGTM!토스트 훅 import가 적절하게 추가되었습니다.
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @src/pages/@owner/menu/hooks/use-menu-list.ts:
- Line 18: The code reads location.state?.formData into foodTruckFormData which
can be undefined on refresh or direct URL access; update use-menu-list to guard
and provide a safe fallback or redirect: detect when foodTruckFormData is
undefined (from location.state?.formData) and either initialize a default form
object (consistent with the form model) or trigger a navigation/early return to
the appropriate entry route, and ensure any downstream usage (e.g., form
initialization or submit handlers) uses the guarded value (foodTruckFormData or
fallback) to avoid runtime errors.
- Around line 47-51: The call to getNavigateState(foodTruckFormData) can pass
undefined because foodTruckFormData is optional; update the getNavigateState
parameter type to accept FoodTruckFormData | undefined (or adjust its overload)
so its signature matches possible undefined input, or add a local type guard in
handleClickBack to only call getNavigateState when foodTruckFormData is defined
and pass a safe fallback state otherwise; reference getNavigateState,
handleClickBack, and foodTruckFormData when making the change.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/pages/@owner/menu/hooks/use-menu-list.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/@owner/menu/hooks/use-menu-list.ts (2)
src/pages/@owner/food-truck-form/utils/navigate-state.tsx (1)
getNavigateState(3-8)src/router/constant/routes.ts (1)
ROUTES(1-33)
🔇 Additional comments (1)
src/pages/@owner/menu/hooks/use-menu-list.ts (1)
53-57:handleRegister는 MenuRegister 컴포넌트에서 사용되지 않는 state를 전달하고 있습니다.MenuRegister 컴포넌트는
location.state를 사용하지 않으며,useParams를 통해서만foodTruckId를 받습니다. 따라서getNavigateState(foodTruckFormData)로 전달되는 state는 실제로 사용되지 않습니다.불필요한 state 전달을 제거하거나, 전달이 필요한 경우
getNavigateState호출 전에foodTruckFormData존재 여부를 확인하는 것이 좋습니다.Likely an incorrect or invalid review comment.
TODO : 서버에 필요한 형식에 맞게 포맷
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts:
- Around line 100-102: The code sets foodTruckServiceAreas from
formData.regionCodes.map(region => region.code!) which unsafely asserts
region.code non-null; change this to safely extract only defined codes by
filtering before mapping (e.g., formData.regionCodes.map(r =>
r.code).filter((c): c is string => !!c) or formData.regionCodes.filter(r =>
r.code != null).map(r => r.code as string)) so foodTruckServiceAreas contains
only valid strings; update the logic in the use-food-truck-form hook where
foodTruckServiceAreas is built to remove any undefined values and preserve
correct typing.
- Line 91: Remove the debug alert call alert('푸드트럭 등록 제출') from
use-food-truck-form.ts (the submission handler in useFoodTruckForm / onSubmit /
handleSubmit) — delete that line and, if user feedback is required, replace it
with the app's standard notification method (e.g., toast or dispatch) or a
console.debug for local debugging.
🧹 Nitpick comments (4)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
89-89:isValid체크가 중복됩니다.
handleSubmit으로 래핑된 콜백 함수 내부에서isValid체크는 불필요합니다.handleSubmit이 이미 폼 유효성 검사를 수행한 후에만 콜백을 호출하기 때문입니다.🔎 간소화 제안
- if (isValid && formData) { + if (formData) { // TODO: 서버에 필요한 형식에 맞게 포맷하여 보내기. 타입 만들어야 함 - alert('푸드트럭 등록 제출'); updateFoodTruckInfo({또는
formData는 항상 존재하므로 조건문 자체를 제거할 수 있습니다:- if (isValid && formData) { - // ... - } + // TODO: 서버에 필요한 형식에 맞게 포맷하여 보내기. 타입 만들어야 함 + updateFoodTruckInfo({ + // ... + });src/pages/@owner/menu/hooks/use-menu-register.ts (1)
8-10: 타입 안전성 및 변수명 개선 제안현재
location.state?.formData에 대한 타입 정의가 없어 런타임 에러 위험이 있습니다. 또한 메뉴 등록 훅에서foodTruckFormData라는 이름은 혼란을 줄 수 있습니다.다음과 같이 개선하는 것을 권장합니다:
location.state에 대한 타입 정의 추가- 변수명을 맥락에 맞게 변경 (예:
preservedFormData또는foodTruckFormState)제안하는 개선 방안
타입 정의를 추가하고 변수명을 개선:
+import type { FoodTruckFormData } from '@pages/@owner/food-truck-form/types'; // 실제 타입 경로로 수정 필요 + +interface LocationState { + formData?: FoodTruckFormData; +} + export const useRegisterMenu = (foodTruckId: number) => { const navigate = useNavigate(); - const location = useLocation(); + const location = useLocation() as { state?: LocationState }; - const foodTruckFormData = location.state?.formData; + const preservedFormData = location.state?.formData;src/pages/@owner/menu/hooks/use-menu-mutations.ts (1)
21-23: 코드 중복 제거 권장동일한 패턴이 세 개의 mutation hook에서 반복됩니다. 커스텀 훅으로 추출하여 재사용성과 유지보수성을 높이는 것을 권장합니다.
제안하는 리팩토링
공통 로직을 추출한 커스텀 훅 생성:
// src/pages/@owner/menu/hooks/use-preserved-form-data.ts import { useLocation } from 'react-router-dom'; import type { FoodTruckFormData } from '@pages/@owner/food-truck-form/types'; interface LocationState { formData?: FoodTruckFormData; } export const usePreservedFormData = () => { const location = useLocation() as { state?: LocationState }; return location.state?.formData; };그런 다음 각 mutation hook에서 사용:
+import { usePreservedFormData } from './use-preserved-form-data'; + export const useRegisterMenuMutation = (foodTruckId: number) => { const queryClient = useQueryClient(); const navigate = useNavigate(); const toast = useToast(); - const location = useLocation(); - - const foodTruckFormData = location.state?.formData; + const foodTruckFormData = usePreservedFormData();Also applies to: 72-74, 119-121
src/pages/@owner/menu/hooks/use-menu-edit.ts (1)
12-14: 타입 안전성 개선 필요 (이전 파일과 동일한 패턴)
use-menu-register.ts와 동일한 타입 안전성 및 변수명 문제가 있습니다. 세 파일 모두에서 동일한 패턴을 사용하므로, 공통 유틸리티로 추출하면 타입 안전성을 한 곳에서 관리할 수 있습니다.앞서 제안한
usePreservedFormData커스텀 훅을 이 파일에도 적용하세요.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/menu/hooks/use-menu-edit.tssrc/pages/@owner/menu/hooks/use-menu-list.tssrc/pages/@owner/menu/hooks/use-menu-mutations.tssrc/pages/@owner/menu/hooks/use-menu-register.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/@owner/menu/hooks/use-menu-list.ts
🧰 Additional context used
🧬 Code graph analysis (2)
src/pages/@owner/menu/hooks/use-menu-mutations.ts (3)
src/router/constant/routes.ts (1)
ROUTES(1-33)src/pages/@owner/menu/api/index.ts (1)
deleteFoodTruckMenu(71-81)src/shared/querykey/food-trucks.ts (1)
FOOD_TRUCKS_QUERY_KEY(3-44)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (6)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (2)
FoodTruckFormData(72-72)foodTruckSchema(15-70)src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
useFoodTruckDetail(16-46)src/pages/@owner/menu/hooks/use-menus-query.ts (1)
useMenusQuery(6-25)src/pages/@owner/food-truck-form/hooks/use-mutation-food-truck-form.ts (1)
useMutationFoodTruckForm(10-36)src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts (1)
resetFoodTruckFormValue(12-57)src/pages/@owner/food-truck-form/constants/food-truck.ts (1)
FOOD_TRUCK_ERROR_MESSAGE(37-88)
🔇 Additional comments (9)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (5)
1-34: LGTM!import 구조가 잘 정리되어 있고,
initialData에서 enum 필드들을undefined로 초기화하는 것은 새 폼에서 사용자가 반드시 선택하도록 유도하는 적절한 패턴입니다.
52-65: LGTM!기존 푸드트럭 데이터와 메뉴 조회 로직이 적절히 구현되었습니다.
useMemo를 사용한menus배열 평탄화와isEdit플래그 설정이 올바릅니다.
67-80: LGTM!데이터 로딩 로직이 잘 구현되었습니다. 신규 등록 시 메뉴 필드만 설정하고, 수정 시 전체 폼을 리셋하는 분기 처리가 적절합니다. 의존성 배열에
toast가 포함되어 이전 리뷰 피드백이 반영되었습니다.
103-103:menuCategories가 하드코딩되어 있습니다.
formData.menuCategories를 사용하지 않고['MEAL']로 하드코딩되어 있습니다. TODO 주석에 따라 추후 수정이 필요한 것으로 보이나, 현재 상태에서는 사용자가 선택한 메뉴 카테고리가 무시됩니다.의도된 동작인지 확인해주세요. 서버에서 요구하는 형식에 따라
formData.menuCategories를 사용하거나 적절한 변환 로직을 추가해야 합니다.
116-123: LGTM!반환 구조가 깔끔하고,
handleSubmit을 미리 바인딩하여 반환하는 패턴이 컴포넌트에서 사용하기 편리합니다.src/pages/@owner/menu/hooks/use-menu-register.ts (2)
19-21: 상태 전달 로직 확인 완료메뉴 목록으로 돌아갈 때 푸드트럭 폼 데이터를 상태로 전달하는 로직이 올바르게 구현되었습니다. 사용자가 메뉴 등록 후 뒤로 가기 시 기존 폼 데이터가 유지됩니다.
1-2: 파일src/pages/@owner/menu/hooks/use-menu-register.ts는 실제로 프로젝트 전체에서 사용되는 표준 경로 alias@router/constant/routes를 올바르게 사용하고 있습니다. 39개 파일이 이 패턴을 따르고 있으며, 불일치는 같은 디렉토리의 다른 파일들(use-menu-mutations.ts, use-menu-edit.ts, use-menu-list.ts)에만 존재합니다.Likely an incorrect or invalid review comment.
src/pages/@owner/menu/hooks/use-menu-mutations.ts (1)
56-58: 상태 전달 로직이 올바르게 구현됨세 개의 mutation(등록, 수정, 삭제) 모두에서 메뉴 목록으로 돌아갈 때 푸드트럭 폼 데이터를 일관되게 전달하고 있습니다. 이를 통해 사용자의 폼 입력 상태가 적절히 보존됩니다.
Also applies to: 103-105, 129-131
src/pages/@owner/menu/hooks/use-menu-edit.ts (1)
39-42: 상태 전달 로직 구현 완료메뉴 수정에서도 뒤로 가기 시 푸드트럭 폼 데이터가 올바르게 전달됩니다. 이제 메뉴 등록, 수정, 삭제의 모든 흐름에서 상태가 일관되게 보존됩니다.
TODO: handleSubmitFoodTruckInfo 함수 유효성 검증 추가 / 닉네임 중복 확인 관련 알맞게 로직 추가
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts:
- Around line 83-101: handleSubmitFoodTruckInfo currently submits without
running the required validations; restore and enforce the nameDuplicate check
and overall form validity before calling updateFoodTruckInfo. Specifically, in
handleSubmitFoodTruckInfo, first check if formData.nameDuplicate is truthy and
if not call setError('name', { message:
FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.required }) and return; then ensure the
form is valid (use the isValid flag and existence of formData) before invoking
updateFoodTruckInfo({ foodTruckId: foodTruckIdNumber, data:
formatFoodTruckForm(formData) }); include any other required field validations
similarly before submission.
In @src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:
- Line 15: The code uses a non-null assertion region.code! when building
foodTruckServiceAreas which breaks type safety; change the expression to safely
filter out undefined codes before mapping (e.g., formData.regionCodes.map(r =>
r.code).filter((c): c is string => c != null) or formData.regionCodes.filter(r
=> r.code != null).map(r => r.code as string)) so foodTruckServiceAreas is a
string[] without relying on !; update the assignment in
format-food-truck-form.ts where foodTruckServiceAreas is set to use this safe
filtering/narrowing.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/pages/@owner/estimate/utils/format-estimate.tssrc/pages/@owner/food-truck-form/api/index.tssrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/hooks/use-mutation-food-truck-form.tssrc/pages/@owner/food-truck-form/utils/format-food-truck-form.tssrc/shared/utils/date/date-formatter.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/pages/@owner/food-truck-form/api/index.ts
- src/pages/@owner/food-truck-form/hooks/use-mutation-food-truck-form.ts
🧰 Additional context used
🧬 Code graph analysis (4)
src/pages/@owner/estimate/utils/format-estimate.ts (1)
src/shared/utils/date/date-formatter.ts (1)
formatAvailableDatesToString(107-118)
src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts (3)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
FoodTruckFormData(72-72)src/pages/@owner/food-truck-form/api/index.ts (1)
UpdateFoodTruckInfoApiRequest(4-19)src/shared/utils/date/date-formatter.ts (1)
formatAvailableDatesToString(107-118)
src/shared/utils/date/date-formatter.ts (1)
src/shared/types/available-date.ts (1)
AvailableDate(2-6)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (6)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (2)
FoodTruckFormData(72-72)foodTruckSchema(15-70)src/pages/food-truck-detail/hooks/use-food-truck-detail.ts (1)
useFoodTruckDetail(16-46)src/pages/@owner/menu/hooks/use-menus-query.ts (1)
useMenusQuery(6-25)src/pages/@owner/food-truck-form/hooks/use-mutation-food-truck-form.ts (1)
useMutationFoodTruckForm(12-38)src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts (1)
resetFoodTruckFormValue(12-57)src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts (1)
formatFoodTruckForm(6-25)
🔇 Additional comments (7)
src/pages/@owner/estimate/utils/format-estimate.ts (1)
5-5: 날짜 포맷팅 로직을 공통 유틸리티로 잘 리팩터링했습니다.인라인으로 작성된 날짜 포맷팅 로직을
formatAvailableDatesToString유틸리티 함수로 대체하여 코드 중복을 제거하고 유지보수성을 개선했습니다.Also applies to: 21-23, 39-41
src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts (1)
6-25: LGTM - 폼 데이터를 API 요청 형식으로 잘 변환합니다.폼 데이터를 API 요청 형식으로 매핑하는 로직이 명확하고,
formatAvailableDatesToString을 사용하여 날짜 변환을 일관되게 처리하고 있습니다.src/shared/utils/date/date-formatter.ts (2)
107-118: LGTM - 역변환 유틸리티가 잘 구현되었습니다.
formatAvailableDatesToString함수는AvailableDate[]를 문자열 배열로 변환하는 역변환 로직을 제공하며,endDate유무에 따른 처리가 적절합니다.
73-102: 함수명 변경이 완전히 적용되었습니다.
formatEstimateDatesToAvailableDates에서formatStringDatesToAvailableDates로의 함수명 변경이 모든 호출처에 정상적으로 반영되었습니다. 기존 함수명에 대한 참조는 없으며, 새로운 함수명이 다음 2곳에서 사용 중입니다:
src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.tssrc/pages/@owner/estimate/hooks/use-estimate-form.tssrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (3)
37-66: LGTM - 데이터 로딩 및 초기화 로직이 잘 구현되었습니다.훅 시그니처를
foodTruckIdNumber를 받도록 변경하고,useFoodTruckDetail과useMenusQuery를 통해 데이터를 로드하는 구조가 명확합니다.isEdit플래그를 통해 수정 모드를 구분하는 것도 적절합니다.
68-81: LGTM - 폼 초기화 로직이 적절하게 구현되었습니다.
useEffect를 사용하여 로드된 데이터로 폼을 초기화하는 로직이 잘 구현되었고, 의존성 배열도 완전합니다. 에러 케이스에 대한 토스트 알림 처리도 적절합니다.
103-110: LGTM - 반환 인터페이스가 적절하게 확장되었습니다.
isEdit플래그와isFormValid상태를 반환하여 컴포넌트에서 폼 상태를 적절히 관리할 수 있도록 구성되었습니다.
src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts
Outdated
Show resolved
Hide resolved
빌드 및 린트 결과모든 검사 통과 🎉
|
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Fix all issues with AI Agents 🤖
In @src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:
- Line 15: The code uses a non-null assertion region.id! when building
foodTruckServiceAreas which can include undefined ids; update the transformation
on formData.regionCodes to first filter out entries where region.id is
null/undefined (e.g., region.id != null) and then map to region.id so the
resulting array contains only defined ids; remove the non-null assertion and
ensure foodTruckServiceAreas receives a strictly typed array of IDs.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/pages/@owner/food-truck-form/utils/format-food-truck-form.tssrc/shared/components/region/components/DepthSection.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts (3)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
FoodTruckFormData(72-72)src/pages/@owner/food-truck-form/api/index.ts (1)
UpdateFoodTruckInfoApiRequest(4-19)src/shared/utils/date/date-formatter.ts (1)
formatAvailableDatesToString(109-120)
🔇 Additional comments (1)
src/shared/components/region/components/DepthSection.tsx (1)
66-70: 이 검토 의견은 근거가 없습니다.RegionResponse타입의 모든 속성(name, id, code)이 선택사항(optional)으로 정의되어 있으므로, 부분 객체{ name, id, code }를RegionResponse타입으로 전달하는 것은 완벽하게 유효한 TypeScript입니다.handleSelectRegion구현은region.code만 사용하며, 제공된 객체가 필요한 모든 속성을 포함하고 있습니다. 타입 안전성에 문제가 없습니다.Likely an incorrect or invalid review comment.
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/menu/hooks/use-menu-list.ts (1)
68-77:handleMenuClick에서도foodTruckFormDataundefined 체크가 필요합니다.
handleMenuClick에서도foodTruckFormData가undefined일 수 있는 경우를 처리해야 합니다. 메뉴 수정 페이지로 이동할 때undefined를 전달하면 폼 데이터가 손실되거나 타입 에러가 발생할 수 있습니다.🔎 제안하는 수정
const handleMenuClick = (foodTruckId?: string, menuId?: string) => () => { if (!foodTruckId || !menuId) { return; } + if (!foodTruckFormData) { + navigate(ROUTES.FOOD_TRUCK_MANAGEMENT); + return; + } const selectedMenu = menus.find(menu => menu.menuId === Number(menuId)); navigate(ROUTES.MENU_EDIT(foodTruckId, menuId), { state: { menuData: selectedMenu, formData: foodTruckFormData }, }); };
🤖 Fix all issues with AI Agents
In @src/pages/@owner/menu/hooks/use-menu-list.ts:
- Around line 61-65: handleRegister currently calls
getNavigateState(foodTruckFormData) without guarding against foodTruckFormData
being undefined; add the same undefined check used in handleClickBack so you
only call navigate with state when foodTruckFormData is defined (or provide a
safe default), and otherwise handle the undefined case (e.g., navigate without
state or show an error). Update the handleRegister function to reference
foodTruckFormData, getNavigateState, and ROUTES.MENU_REGISTER accordingly so the
type error and unexpected behavior are avoided.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/pages/@owner/menu/hooks/use-menu-list.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
📚 Learning: 2026-01-06T03:26:46.868Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/menu/hooks/use-menu-list.ts
📚 Learning: 2026-01-06T03:26:08.240Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:0-0
Timestamp: 2026-01-06T03:26:08.240Z
Learning: In the ChaCall-FE codebase, region.code in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.code are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/menu/hooks/use-menu-list.ts
🧬 Code graph analysis (1)
src/pages/@owner/menu/hooks/use-menu-list.ts (2)
src/router/constant/routes.ts (1)
ROUTES(1-33)src/pages/@owner/food-truck-form/utils/navigate-state.tsx (1)
getNavigateState(3-8)
🔇 Additional comments (1)
src/pages/@owner/menu/hooks/use-menu-list.ts (1)
48-51:foodTruckFormData가 없을 때의 안전한 처리가 추가되었습니다.
handleClickBack에서foodTruckFormData가 없을 경우FOOD_TRUCK_MANAGEMENT로 이동하도록 가드를 추가한 것은 좋은 개선입니다. 이를 통해 사용자가 페이지 새로고침이나 직접 URL 접근 시 안전하게 처리됩니다.
TODO: 푸드트럭 등록/수정 form에 대한 전체적인 유효성 검증 확인 및 수정
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/food-truck-form/hooks/use-basic-info.ts (1)
37-49: 응답이 undefined인 경우를 명시적으로 처리해야 합니다.41번 라인의
!response?.duplicated조건은response가 undefined이거나 null일 때도 참으로 평가되어, API 응답이 없거나 실패한 경우에도 이름을 사용 가능한 것으로 처리합니다. 이는 유효하지 않은 이름이 검증을 통과할 수 있는 위험이 있습니다.제안하는 수정 방안
const checkNameDuplicated = async () => { const name = formData.name; const response = await handleCheckName(name); + if (!response) { + setError('name', { + message: '이름 중복 확인에 실패했습니다. 다시 시도해주세요.', + }); + return; + } + - if (!response?.duplicated) { + if (!response.duplicated) { setValue('nameDuplicate', true, { shouldValidate: true }); } else { setValue('nameDuplicate', false, { shouldValidate: true }); setError('name', { message: FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.duplicated, }); } };
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/pages/@owner/food-truck-form/hooks/use-basic-info.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
🧬 Code graph analysis (1)
src/pages/@owner/food-truck-form/hooks/use-basic-info.ts (1)
src/pages/@owner/food-truck-onboarding/hooks/use-food-truck-name.ts (1)
useFoodTruckName(7-44)
🔇 Additional comments (2)
src/pages/@owner/food-truck-form/hooks/use-basic-info.ts (2)
9-9: 이름 중복 확인 기능 통합이 적절합니다.
useFoodTruckName훅을 통한 이름 중복 검증 로직 통합이 깔끔하게 구현되었습니다.Also applies to: 20-20
27-31: 이름 변경 시 검증 상태 초기화 로직이 올바릅니다.이름이 변경될 때
resetVerification()과nameDuplicate초기화를 모두 수행하여 사용자가 새 이름을 다시 검증하도록 강제하는 것이 적절합니다.
빌드 및 린트 결과모든 검사 통과 🎉
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
18-36: initialData의 isNameDuplicated 기본값이 잘못되었습니다.Line 21에서
isNameDuplicated: true로 설정되어 있지만, 스키마는 이 값이false여야 한다고 요구합니다. 신규 등록 시 폼이 즉시 유효하지 않은 상태가 됩니다.🐛 수정 방안
const initialData = { name: '', isNameChecked: false, - isNameDuplicated: true, + isNameDuplicated: false, description: '', phoneNumber: '',
🤖 Fix all issues with AI agents
In @src/pages/@owner/food-truck-form/FoodTruckForm.tsx:
- Around line 69-72: The validation that checks foodTruckId and
isNaN(foodTruckIdNumber) shows a toast and calls navigate but doesn't stop
execution, causing the component (FoodTruckForm) to continue rendering with
invalid data; fix by performing this check inside a useEffect (recommended) that
runs on mount and calls toast.error(...) and
navigate(ROUTES.FOOD_TRUCK_MANAGEMENT) when invalid, or if you prefer a smaller
change, add an immediate early return after navigate (e.g., return null or
return) so the rest of FoodTruckForm's render/logic doesn't run when the id is
invalid.
In @src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts:
- Line 46: The schema relaxed validation by replacing
z.array(z.nativeEnum(FOOD_CATEGORIES)) with z.array(z.string()), allowing
invalid categories; restore strict enum validation by changing menuCategories
back to z.array(z.nativeEnum(FOOD_CATEGORIES)) (or if FOOD_CATEGORIES isn't
available, use z.array(z.enum([...allowedCategoryStrings...]))) and ensure
FOOD_CATEGORIES is imported/available where the schema (menuCategories) is
defined so the runtime and TypeScript types remain aligned.
- Around line 41-46: The schema currently uses
z.enum(Object.values(...).map(...)) which supplies a runtime string[] and loses
type safety; restore type-safe enums by switching back to z.nativeEnum with the
original constant enums (use z.nativeEnum(AVAILABLE_QUANTITY),
z.nativeEnum(NEED_ELECTRICITY), z.nativeEnum(PAYMENT_METHOD)) and revert
menuCategories to z.nativeEnum(FOOD_CATEGORIES) or, if you must use z.enum,
convert the arrays to readonly tuple literal types and assert their type
appropriately so Zod accepts them; update the schema entries for
availableQuantity, needElectricity, paymentMethod, and menuCategories
accordingly.
🧹 Nitpick comments (2)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
20-21: 중복 확인 검증 로직을 개선하세요.
isNameDuplicated가 반드시false여야 한다면, 명시적인 에러 메시지를 제공하는 것이 좋습니다.♻️ 개선된 검증 로직
- isNameChecked: z.boolean(), - isNameDuplicated: z.boolean().refine(v => v === false), + isNameChecked: z.boolean().refine(v => v === true, { + message: FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.required, + }), + isNameDuplicated: z.boolean().refine(v => v === false, { + message: FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.duplicated, + }),src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
69-82: 데이터 로딩 useEffect의 의존성 배열을 확인하세요.
reset과setValue를 의존성 배열에 포함하면 불필요한 재실행이 발생할 수 있습니다. React Hook Form의 이러한 함수들은 참조가 안정적이지만, 명시적으로 제외하는 것을 고려하세요.♻️ 개선 제안
useEffect(() => { if (!foodTruckDetailData) { setValue('menus', menus && menus.length > 0, { shouldValidate: true }); return; } const result = resetFoodTruckFormValue(foodTruckDetailData, menus); if (result.isError) { toast.error('잘못된 정보입니다. 다시 시도해주세요.'); return; } reset(result.values); - }, [foodTruckDetailData, menus, toast, reset, setValue]); + }, [foodTruckDetailData, menus, toast]);또는 ESLint 경고를 방지하려면 주석으로 명시:
}, [foodTruckDetailData, menus, toast, reset, setValue]); // reset과 setValue는 안정적인 참조
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/pages/@owner/food-truck-form/@section/basic-info-section/FoodTruckName.tsxsrc/pages/@owner/food-truck-form/FoodTruckForm.tsxsrc/pages/@owner/food-truck-form/hooks/use-basic-info.tssrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- src/pages/@owner/food-truck-form/utils/reset-food-truck-form-value.ts
- src/pages/@owner/food-truck-form/hooks/use-basic-info.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/menu/hooks/use-menu-list.ts:61-65
Timestamp: 2026-01-06T04:01:35.227Z
Learning: In src/pages/owner/menu/hooks/use-menu-list.ts, formData validation is only required when navigating to FOOD_TRUCK_FORM (via handleClickBack), not when navigating to MENU_REGISTER (via handleRegister), as MENU_REGISTER doesn't require formData to be defined.
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
📚 Learning: 2026-01-06T04:01:35.227Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/menu/hooks/use-menu-list.ts:61-65
Timestamp: 2026-01-06T04:01:35.227Z
Learning: In src/pages/owner/menu/hooks/use-menu-list.ts, formData validation is only required when navigating to FOOD_TRUCK_FORM (via handleClickBack), not when navigating to MENU_REGISTER (via handleRegister), as MENU_REGISTER doesn't require formData to be defined.
Applied to files:
src/pages/@owner/food-truck-form/@section/basic-info-section/FoodTruckName.tsxsrc/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
📚 Learning: 2026-01-06T03:26:46.868Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
📚 Learning: 2026-01-06T03:26:08.240Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:0-0
Timestamp: 2026-01-06T03:26:08.240Z
Learning: In the ChaCall-FE codebase, region.code in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.code are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.tssrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
🧬 Code graph analysis (3)
src/pages/@owner/food-truck-form/@section/basic-info-section/FoodTruckName.tsx (1)
src/pages/@owner/food-truck-form/hooks/use-basic-info.ts (1)
useBasicInfo(12-152)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (4)
src/pages/@owner/food-truck-form/constants/food-truck.ts (2)
FOOD_TRUCK_MAX_LENGTH(1-35)FOOD_TRUCK_ERROR_MESSAGE(37-88)src/shared/constant/available-quantity.ts (1)
AVAILABLE_QUANTITY(1-7)src/shared/constant/need-electricity.ts (1)
NEED_ELECTRICITY(1-5)src/shared/constant/payment-method.ts (1)
PAYMENT_METHOD(1-5)
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (5)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(38-106)src/router/constant/routes.ts (1)
ROUTES(1-33)src/shared/components/layout/navigation/Navigation.tsx (1)
Navigation(13-61)src/shared/components/icon/Icon.tsx (1)
Icon(58-93)src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx (1)
RegionSection(15-47)
🔇 Additional comments (7)
src/pages/@owner/food-truck-form/@section/basic-info-section/FoodTruckName.tsx (2)
9-24: 새로운 중복 확인 로직이 올바르게 구현되었습니다.
previousNameprop을 통해 기존 이름을 전달받고,isNameChecked와isNameDuplicated를 분리하여 더 명확한 상태 관리를 제공합니다.
45-50: 성공 메시지 표시 조건이 정확합니다.
isNameChecked && !isNameDuplicated조건으로 중복 확인이 완료되고 중복되지 않은 경우에만 성공 메시지가 표시됩니다.src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (2)
59-72: 메뉴 데이터 로딩 및 계산 로직이 올바릅니다.
useMemo를 사용하여 페이지 데이터를 효율적으로 평탄화하고, 메뉴 존재 여부를 정확하게 폼 상태에 반영합니다.
84-95: 에러 처리는 이미 mutation hook에서 구현되어 있습니다.
useMutationFoodTruckForm의onError콜백(30-32줄)에서 API 에러를 처리하고 사용자에게 토스트 메시지로 알립니다. React Query의useMutation은 이렇게 mutation 수준에서 에러를 처리하는 것이 표준 패턴이므로, form handler에서 추가 try-catch가 필요하지 않습니다.Likely an incorrect or invalid review comment.
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (3)
81-81: 네비게이션 텍스트가 올바르게 동적으로 설정됩니다.
isEdit상태에 따라 "나의 푸드트럭 수정" 또는 "나의 푸드트럭 등록"이 표시됩니다. 데이터 로딩 중 짧은 깜빡임이 발생할 수 있지만 허용 가능한 수준입니다.
63-67: 다른 페이지에서 돌아올 때 폼 상태를 올바르게 복원합니다.location state를 통한 폼 데이터 복원 로직이 정확하게 구현되어 있습니다.
86-86: 코드가 이미undefined처리를 올바르게 구현했습니다.
FoodTruckName컴포넌트의previousName프로퍼티는previousName?: string으로 선택적 타입으로 정의되어 있으며,useBasicInfo훅도previousName?: string으로 옵셔널 파라미터를 받도록 구현되어 있습니다. 데이터 로딩 중이나 새로운 푸드트럭 생성 시previousName이undefined일 수 있지만, 모든 곳에서 이미 안전하게 처리되고 있습니다.
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts
Outdated
Show resolved
Hide resolved
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts
Outdated
Show resolved
Hide resolved
빌드 및 린트 결과모든 검사 통과 🎉
|
빌드 및 린트 결과일부 검사 실패
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (1)
38-47: 유효하지 않은 route param이useFoodTruckForm(NaN)으로 흘러갈 수 있음Line 38-46에서
foodTruckId가 없거나 숫자가 아니면foodTruckIdNumber가NaN인데, 현재는 Line 45-46에서 유효성 검사 전에 바로useFoodTruckForm(foodTruckIdNumber)를 호출합니다.비록 내부의
useFoodTruckDetail,useMenusQuery는enabled: !!foodTruckId가드로 쿼리 실행을 방지하지만, 여전히 문제가 있습니다:
- 쿼리 키가 NaN 값으로 오염됨
- 유효성 검사를 지나
updateMyFoodTruckInfoApi(NaN)이 실행되면/food-trucks/NaN엔드포인트로 API 호출- 아키텍처적으로 검증 후 사용 원칙 위반
useFoodTruckForm의 인자를number | null로 받아 내부에서 invalid 상태를 조기 처리하거나, 혹은 FoodTruckForm에서 검증 후 호출하는 것이 안전합니다.
🤖 Fix all issues with AI agents
In @src/pages/@owner/food-truck-form/FoodTruckForm.tsx:
- Around line 69-73: The render block that calls toast.error and navigate when
checking foodTruckId/isNaN runs side-effects during render; move this logic into
a useEffect that depends on foodTruckId (and foodTruckIdNumber) so toast.error
and navigate(ROUTES.FOOD_TRUCK_MANAGEMENT) are invoked only as effects, and call
navigate with { replace: true } to avoid leaving the bad URL in history; keep
the component returning null (or a loading state) while the effect runs and
ensure you import/use React's useEffect.
In @src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts:
- Around line 17-22: Add schema-level validation for isNameChecked by replacing
its current z.boolean() with z.literal(false) or z.boolean().refine to assert
false and include the correct error message key
FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.required; update the isNameChecked entry
in the food-truck-form.schema (the isNameChecked symbol) to use z.literal(false,
{ errorMap: ... }) or .refine(v => v === false, { message:
FOOD_TRUCK_ERROR_MESSAGE.nameDuplicate.required }) similar to how menus uses
refine so the validator emits the user-facing message '푸드트럭 이름을 중복확인해주세요.'
instead of the undefined path.
🧹 Nitpick comments (1)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
8-13:isNameDuplicated검증에 에러 메시지 추가 권장
z.boolean().refine(v => v === false)는 함수 참조 가능하지만, 실패 시 generic 에러를 노출합니다. 더 명확한 UX를 위해 다음과 같이 개선할 수 있습니다:isNameDuplicated: z.boolean().refine( v => v === false, { message: FOOD_TRUCK_ERROR_MESSAGE.name.duplicated } ) // 또는 더 간단하게: isNameDuplicated: z.literal(false)참고:
validateFoodTruckFormTime는 Zod v4.1.8에서superRefine((value, ctx) => ...)의 정확한 시그니처를 구현하고 있으며,z.custom<RegionResponse>()/z.custom<AvailableDate>()는 런타임 검증 없이 타입만 제공하는 현재 패턴이 일관되게 적용되고 있습니다.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/pages/@owner/food-truck-form/FoodTruckForm.tsxsrc/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/menu/hooks/use-menu-list.ts:61-65
Timestamp: 2026-01-06T04:01:35.227Z
Learning: In src/pages/owner/menu/hooks/use-menu-list.ts, formData validation is only required when navigating to FOOD_TRUCK_FORM (via handleClickBack), not when navigating to MENU_REGISTER (via handleRegister), as MENU_REGISTER doesn't require formData to be defined.
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
📚 Learning: 2026-01-06T04:01:35.227Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/menu/hooks/use-menu-list.ts:61-65
Timestamp: 2026-01-06T04:01:35.227Z
Learning: In src/pages/owner/menu/hooks/use-menu-list.ts, formData validation is only required when navigating to FOOD_TRUCK_FORM (via handleClickBack), not when navigating to MENU_REGISTER (via handleRegister), as MENU_REGISTER doesn't require formData to be defined.
Applied to files:
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
📚 Learning: 2026-01-06T03:26:46.868Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:15-15
Timestamp: 2026-01-06T03:26:46.868Z
Learning: In the ChaCall-FE codebase, region.id in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.id are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
📚 Learning: 2026-01-06T03:26:08.240Z
Learnt from: holdn2
Repo: CHA-CALL/ChaCall-FE PR: 214
File: src/pages/@owner/food-truck-form/utils/format-food-truck-form.ts:0-0
Timestamp: 2026-01-06T03:26:08.240Z
Learning: In the ChaCall-FE codebase, region.code in RegionResponse is marked as optional in the Swagger spec, but in practice it cannot be undefined when used in the food truck form context. Exception handling for invalid region data is already in place elsewhere in the codebase, so non-null assertions on region.code are acceptable in format-food-truck-form.ts.
Applied to files:
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.tssrc/pages/@owner/food-truck-form/FoodTruckForm.tsx
🧬 Code graph analysis (1)
src/pages/@owner/food-truck-form/FoodTruckForm.tsx (4)
src/pages/@owner/food-truck-form/hooks/use-food-truck-form.ts (1)
useFoodTruckForm(38-106)src/router/constant/routes.ts (1)
ROUTES(1-33)src/shared/components/layout/navigation/Navigation.tsx (1)
Navigation(13-61)src/pages/@owner/food-truck-form/@section/region-section/RegionSection.tsx (1)
RegionSection(15-47)
🔇 Additional comments (3)
src/pages/@owner/food-truck-form/schemas/food-truck-form.schema.ts (1)
23-32: Zod v4.1.8에서.max(limit, messageString)오버로드가 공식 지원되므로 현재 구현은 호환성 문제 없습니다.리포지토리에서 사용 중인 Zod v4.1.8은
.max(length, "message")형태의 메시지 문자열 오버로드를 정식으로 지원하므로, 추가 마이그레이션 없이 현재 코드 형태(description.max메시지 추가)로 안전하게 진행 가능합니다.src/pages/@owner/food-truck-form/FoodTruckForm.tsx (2)
7-9: import 추가는 방향성 OK (ROUTES/toast 사용 일관성 유지)
ROUTES로 라우팅 상수화하고useToast로 피드백 주는 흐름은 좋습니다.
82-98: 편집/등록 타이틀,previousName,RegionSection foodTruckId전달은 의도 명확
- Line 82:
isEdit기반 타이틀 분기는 UX적으로 직관적입니다.- Line 87:
previousName를 내려주는 건 “이름 변경 없으면 중복 체크 스킵/유지” 같은 로직 구현에 도움이 됩니다.- Line 97:
RegionSection에foodTruckId를 넘겨서 라우팅 생성에 쓰는 흐름도 자연스럽습니다.
다만previousName이undefined일 때FoodTruckName이 안전하게 처리되는지, 그리고 기존 이름과 동일할 때 중복확인 플래그(isNameChecked)가 의도대로 유지되는지만 확인 부탁드립니다.
빌드 및 린트 결과모든 검사 통과 🎉
|
📌 Related Issues
✅ 체크 리스트
📄 Tasks
⭐ PR Point (To Reviewer)
📷 Screenshot
🔔 ETC
Summary by CodeRabbit
새로운 기능
개선사항
✏️ Tip: You can customize this high-level summary in your review settings.